﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using PdfSharp.Pdf;
using PdfSharp.Drawing;
using System.IO;
using System.Globalization;
using PdfSharp.Charting;
using Model;
using BLL;
using HRP.Utilidades;

namespace HRP.Private.Impressoes
{
    public partial class SS : System.Web.UI.Page
    {
        private string font = "Verdana";
        private string TituloLabel = "INSTITUTO NACIONAL DE SEGURANÇA SOCIAL";
        private string SegundoTituloLabel = "FOLHA DE CÁLCULO DE DESCONTOS DE CONTRIBUIÇÃO PARA O FUNDO SEGURANÇA SOCIAL";
        private string TabelaNumLabel = "Nº";
        private string TabelaNumLabel2 = "Ord";
        private string NomeFuncLabel = "Nome";
        private string NumeroFuncLabel = "Número";
        private string SalarioFuncLabel = "Salário";
        private string SalarioFuncLabel2 = "Base";
        private string RendAdicionaisFuncLabel = "Rendimentos";
        private string RendAdicionaisFuncLabel2 = "Adicionais";
        private string DescontoLabel = "SS";
        private string DepartamentoLabel = "Sector";
        private string CargoLabel = "Categoria";
        private string NumContribuinteLabel = "Nº Contribuinte: ";
        private string NumSSLabel = "Nº Segurança Social: ";
        private string NomeEmpresaLabel = "Entidade: ";
        private string autor = "HR Portal";
        private string assunto = "Comprovativo Segurança Social";
        private string TotalLabel = "Total";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["id"] != null && Session["EmpresaActual"] != null)
            {
                int facturaId = 0;
                Int32.TryParse(Request.QueryString["id"], out facturaId);
                hrp_empresas empresa = (hrp_empresas)Session["EmpresaActual"];
                var ActualListaImpressao = Facturacao_BLL.Instance.ListaFacturacaoDetalhada(facturaId);
                HashSet<int> validosIds = new HashSet<int>();
                if (Request.QueryString["reciboid"] != null)
                {
                    string[] ids = Request.QueryString["reciboid"].ToString().Split('_');
                    foreach (string receivedId in ids)
                    {
                        int id = 0;
                        Int32.TryParse(receivedId, out id);
                        if (id != 0)
                            validosIds.Add(id);
                    }
                    ActualListaImpressao = ActualListaImpressao.Where(f => validosIds.Contains(f.id)).ToList();
                }
                List<FuncionarioDetalhe> list = new List<FuncionarioDetalhe>();
                foreach (hrp_facturacao_funcionario_detalhe func in ActualListaImpressao)
                    if (validosIds.Count == 0 || (validosIds.Count > 0 && validosIds.Contains(func.id)))
                    {
                        list.Add(new FuncionarioDetalhe()
                        {
                            numFuncionario = func.numero_funcionario.ToString(),
                            nome = func.nome_func,
                            departamento = func.departamento,
                            cargo = func.cargo,
                            salarioBase = func.salarioBruto.ToString(),
                            rendimentosAdicionais = (func.total_abonos - func.salarioBruto).ToString(),
                            desconto = func.valor_desconto_ss.ToString()
                        });
                    }

                string totalDesconto = ActualListaImpressao.Sum(x => x.valor_desconto_ss).ToString();
                var listaOrdenada = list.OrderBy(f => f.nome).ToList();
                ImprimirListaFacturas(listaOrdenada,totalDesconto, ActualListaImpressao, empresa);
            }
        }

        private void ImprimirListaFacturas(List<FuncionarioDetalhe> list,string resumoTotal,
            List<hrp_facturacao_funcionario_detalhe> ActualListaImpressao, hrp_empresas empresa)
        {
            PdfDocument document = new PdfDocument();
            hrp_facturacao_funcionario_detalhe primeiroFuncionario = ActualListaImpressao[0];
            string tituloDocumento = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(Convert.ToInt32(primeiroFuncionario.mes_referente)) + " " + primeiroFuncionario.ano_referente;
            document.Info.Title = DescontoLabel + " " + tituloDocumento;
            document.Info.Author = autor;
            document.Info.Subject = assunto;
            int inicio = 0;
            int fim = 25;
            bool primeiraPag = true;
            while (inicio < list.Count)
            {
                PdfPage page = document.AddPage();
                XGraphics gfx = XGraphics.FromPdfPage(page);
                page.Width = XUnit.FromMillimeter(297); // A4
                page.Height = XUnit.FromMillimeter(210);
                int posY = primeiraPag ? 170 : 25;
                if (primeiraPag)
                {
                    string dataRecibo = new CultureInfo("pt-PT").DateTimeFormat.GetMonthName(Convert.ToInt32(primeiroFuncionario.mes_referente)) + " " + primeiroFuncionario.ano_referente;
                    AdicionarCabecalho(ref gfx, Server.MapPath(empresa.logo), dataRecibo, empresa.nome, empresa.nif, empresa.ss);
                    primeiraPag = false;
                }
                CriarTabela(ref gfx, list, inicio,ref fim, Math.Min(fim, list.Count),ref posY, true);
                inicio = fim;
                fim += 35;
                if (inicio >= list.Count)
                    CriarLinhaTotal(ref gfx, posY, resumoTotal);
            }


            // Send PDF to browser
            MemoryStream stream = new MemoryStream();
            document.Save(stream, false);
            Response.Clear();
            Response.ContentType = "application/pdf";
            Response.AddHeader("content-length", stream.Length.ToString());
            Response.BinaryWrite(stream.ToArray());
            Response.Flush();
            stream.Close();
            Response.End();
        }


        private void CriarLinhaTotal(ref XGraphics gfx, int posYInicial, string resumoTotal)
        {
            if (!string.IsNullOrEmpty(resumoTotal))
            {
                XRect linhaTabela = new XRect(700, posYInicial, 120, 20);
                gfx.DrawLine(XPens.Black, new XPoint(700, posYInicial), new XPoint(700, posYInicial + 20));

                gfx.DrawRectangle(XPens.Black, linhaTabela);
                gfx.DrawString(TotalLabel, new XFont(font, 9, XFontStyle.Bold), XBrushes.Black, 660, posYInicial + 16);
                gfx.DrawString(resumoTotal, new XFont(font, 8), XBrushes.Black, 702, posYInicial + 16);
            }
        }

        private void AdicionarCabecalho(ref XGraphics gfx, string logoEmpresaUrl, string mesRecibo, string nomeEmpresa, string nifEmpresa, string ssEmpresa)
        {
            //logotipo
            XImage logotipo = XImage.FromFile(logoEmpresaUrl);
            XRect rectLogotipo = new XRect(20, 20, 180, 90);
            gfx.DrawImage(logotipo, rectLogotipo);
            gfx.DrawString(TituloLabel, new XFont(font, 12, XFontStyle.Bold), XBrushes.Black, 210, 55);
            gfx.DrawString(SegundoTituloLabel, new XFont(font, 12, XFontStyle.Bold), XBrushes.Black, 210, 75);
            gfx.DrawString(mesRecibo, new XFont(font, 12, XFontStyle.Bold), XBrushes.Black, 645, 135);
            //dados Empresa
            gfx.DrawString(NomeEmpresaLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 20, 125);
            gfx.DrawString(nomeEmpresa, new XFont(font, 10), XBrushes.Black, 150, 125);
            gfx.DrawString(NumContribuinteLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 20, 140);
            gfx.DrawString(nifEmpresa, new XFont(font, 10), XBrushes.Black, 150, 140);
            gfx.DrawString(NumSSLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 20, 155);
            gfx.DrawString(ssEmpresa, new XFont(font, 10), XBrushes.Black, 150, 155);

        }

        private void PartirValorEmDuasLinhas(string valor, int max, out string primeiraLinha, out string segundaLinha)
        {
            string[] arr = valor.Split(' ');
            primeiraLinha = arr[0];
            int pos = 1;
            while (arr[pos].Length + primeiraLinha.Length < max)
            {
                primeiraLinha += " " + arr[pos];
                pos++;
                if (pos == arr.Length)
                    break;
            }
            segundaLinha = valor.Substring(primeiraLinha.Length + 1).Trim(' ');
        }

        private void CriarTabela(ref XGraphics gfx, List<FuncionarioDetalhe> list, int inicio, ref int fim, int maxFim, ref int posYInicial, bool incluirCabecalho)
        {
            if (incluirCabecalho)
            {
                XRect cabecalhoTabela = new XRect(20, posYInicial, 800, 30);
                gfx.DrawRectangle(XPens.Black, cabecalhoTabela);
                gfx.DrawLine(XPens.Black, new XPoint(45, posYInicial), new XPoint(45, posYInicial + 30));
                gfx.DrawLine(XPens.Black, new XPoint(93, posYInicial), new XPoint(93, posYInicial + 30));
                gfx.DrawLine(XPens.Black, new XPoint(300, posYInicial), new XPoint(300, posYInicial + 30));
                gfx.DrawLine(XPens.Black, new XPoint(420, posYInicial), new XPoint(420, posYInicial + 30));
                gfx.DrawLine(XPens.Black, new XPoint(540, posYInicial), new XPoint(540, posYInicial + 30));
                gfx.DrawLine(XPens.Black, new XPoint(620, posYInicial), new XPoint(620, posYInicial + 30));
                gfx.DrawLine(XPens.Black, new XPoint(700, posYInicial), new XPoint(700, posYInicial + 30));

                gfx.DrawString(TabelaNumLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 23, posYInicial + 13);
                gfx.DrawString(TabelaNumLabel2, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 23, posYInicial + 27);
                gfx.DrawString(NumeroFuncLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 48, posYInicial + 20);
                gfx.DrawString(NomeFuncLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 96, posYInicial + 20);
                gfx.DrawString(DepartamentoLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 303, posYInicial + 20);
                gfx.DrawString(CargoLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 423, posYInicial + 20);
                gfx.DrawString(SalarioFuncLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 543, posYInicial + 13);
                gfx.DrawString(SalarioFuncLabel2, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 543, posYInicial + 27);
                gfx.DrawString(RendAdicionaisFuncLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 623, posYInicial + 13);
                gfx.DrawString(RendAdicionaisFuncLabel2, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 623, posYInicial + 27);
                gfx.DrawString(DescontoLabel, new XFont(font, 10, XFontStyle.Bold), XBrushes.Black, 703, posYInicial + 20);
                posYInicial += 30;
            }
            for (int i = inicio; i < maxFim; i++)
            {
                FuncionarioDetalhe detalhe = list[i];
                int maxCargo = 25;
                int maxNome = 47;
                int maxDepartamento = 25;
                int alturaLinha = detalhe.cargo.Length <= maxCargo
                                   && detalhe.nome.Length <= maxNome
                                   && detalhe.departamento.Length <= maxDepartamento ? 15 : 30;
                int comecoYEscrita = alturaLinha == 15 ? 12 : 20;
                int comecoY1 = 13;
                int comecoY2 = 27;
                XRect linhaTabela = new XRect(20, posYInicial, 800, alturaLinha);
                gfx.DrawLine(XPens.Black, new XPoint(45, posYInicial), new XPoint(45, posYInicial + alturaLinha));
                gfx.DrawLine(XPens.Black, new XPoint(93, posYInicial), new XPoint(93, posYInicial + alturaLinha));
                gfx.DrawLine(XPens.Black, new XPoint(300, posYInicial), new XPoint(300, posYInicial + alturaLinha));
                gfx.DrawLine(XPens.Black, new XPoint(420, posYInicial), new XPoint(420, posYInicial + alturaLinha));
                gfx.DrawLine(XPens.Black, new XPoint(540, posYInicial), new XPoint(540, posYInicial + alturaLinha));
                gfx.DrawLine(XPens.Black, new XPoint(620, posYInicial), new XPoint(620, posYInicial + alturaLinha));
                gfx.DrawLine(XPens.Black, new XPoint(700, posYInicial), new XPoint(700, posYInicial + alturaLinha));

                gfx.DrawRectangle(XPens.Black, linhaTabela);
                gfx.DrawString((i + 1).ToString(), new XFont(font, 8), XBrushes.Black, 22, posYInicial + comecoYEscrita);
                gfx.DrawString(detalhe.numFuncionario, new XFont(font, 8), XBrushes.Black, 46, posYInicial + comecoYEscrita);
                //nome
                if (detalhe.nome.Length <= maxNome)
                {
                    gfx.DrawString(detalhe.nome, new XFont(font, 8), XBrushes.Black, 95, posYInicial + comecoYEscrita);
                }
                else
                {
                    string primeiraLinha, segundaLinha = string.Empty;
                    PartirValorEmDuasLinhas(detalhe.nome, maxNome, out primeiraLinha, out segundaLinha);
                    gfx.DrawString(primeiraLinha, new XFont(font, 8), XBrushes.Black, 95, posYInicial + comecoY1);
                    gfx.DrawString(segundaLinha, new XFont(font, 8), XBrushes.Black, 95, posYInicial + comecoY2);
                }
                //departamento
                if (detalhe.departamento.Length <= maxDepartamento)
                {
                    gfx.DrawString(detalhe.departamento, new XFont(font, 8), XBrushes.Black, 302, posYInicial + comecoYEscrita);
                }
                else
                {
                    string primeiraLinha, segundaLinha = string.Empty;
                    PartirValorEmDuasLinhas(detalhe.departamento, maxDepartamento, out primeiraLinha, out segundaLinha);
                    gfx.DrawString(primeiraLinha, new XFont(font, 8), XBrushes.Black, 302, posYInicial + comecoY1);
                    gfx.DrawString(segundaLinha, new XFont(font, 8), XBrushes.Black, 302, posYInicial + comecoY2);
                }
                //cargo
                if (detalhe.cargo.Length <= maxCargo)
                {
                    gfx.DrawString(detalhe.cargo, new XFont(font, 8), XBrushes.Black, 422, posYInicial + comecoYEscrita);
                }
                else
                {
                    string primeiraLinha, segundaLinha = string.Empty;
                    PartirValorEmDuasLinhas(detalhe.cargo, maxCargo, out primeiraLinha, out segundaLinha);
                    gfx.DrawString(primeiraLinha, new XFont(font, 8), XBrushes.Black, 422, posYInicial + comecoY1);
                    gfx.DrawString(segundaLinha, new XFont(font, 8), XBrushes.Black, 422, posYInicial + comecoY2);
                }

                gfx.DrawString(detalhe.salarioBase, new XFont(font, 8), XBrushes.Black, 542, posYInicial + comecoYEscrita);
                gfx.DrawString(detalhe.rendimentosAdicionais, new XFont(font, 8), XBrushes.Black, 622, posYInicial + comecoYEscrita);
                gfx.DrawString(detalhe.desconto, new XFont(font, 8), XBrushes.Black, 702, posYInicial + comecoYEscrita);
                posYInicial += alturaLinha;
                if (posYInicial > 525)
                {
                    fim = i + 1;
                    break;
                }
            }

        }
    }
}